iT邦幫忙

2023 iThome 鐵人賽

DAY 28
0
Cloud Native

【하나, 둘, ready, get set, go】系列 第 28

【하나, 둘, ready, get set, go】Day 28 - 將服務部署上 Kubernetes 上吧 feat. minikube

  • 分享至 

  • xImage
  •  

前情提要

昨天透過 GitLab CI 成功自動化編譯多架構 Docker Image 後,接下來就要實際部署上 Kubernetes 來進行管理啦

Kubernetes 簡單介紹

Kubernetes 是一用於「自動部署、擴充和管理容器化應用程式」的開源系統,其旨在提供「跨主機叢集的自動部署、擴充以及執行應用程式容器的平台」,於 2014 年由 Google 公布,並於隔年 2015 年正式推出 v1.0,並捐贈給 CNCF (Cloud Native Computing Foundation)

下圖為 Kubernetes 架構圖,主要分為兩大部分

  1. Control Plane (主節點)
  2. Worker Node (工作節點)

Kubernetes 架構圖
▲ 圖取自 Kubernetes Documentation

Control Plane

  • kube-apiserver
    • 說明:kube-apiserver 主要用於對外公開 Kubernetes API,其旨在透過部署更多實例來進行水平擴展
  • etcd
    • 說明:etcd 為一具持續且高可用的 key-value 資料庫,用作於所有 Kubernetes 叢集的後端儲存
  • kube-scheduler
    • 說明:kube-scheduler 用於觀察新建立且尚未指派於節點上的 Pod,並選擇一節點去執行
  • kube-controller-manager
    • 說明:負責執行 controller 的 process
  • cloud-controller-manager
    • 說明:負責與雲端服務提供商的 API 進行互動

Worker Node

  • kubelet
    • 說明:執行在叢集中的每個節點的代理,用於確保 Container 有在 Pod 上執行
  • kube-proxy
    • 說明:kube-proxy 為一網路代理,在叢集中的每個節點上執行
  • Container runtime
    • 說明:讓 Kubernetes 可以有效執行容器的基本元件,負責管理 Kubernetes 環境中容器的執行與生命週期

minikube 簡單介紹

這邊我們會透過由 Google 釋出的本地 Kubernetes 叢集環境 minikube,在本地快速建立 Kubernetes 叢集環境

minikube
https://minikube.sigs.k8s.io/docs/

實際操作

安裝 minikube

https://minikube.sigs.k8s.io/docs/start/

minikube 官網提供了 Linux、macOS、Windows 這三套系統的安裝方式

這裡我們的環境為 macOS,M1 為 ARM64 架構的
所以我們就選擇「macOS、ARM64」,版本就選擇「Stable」穩定版本、安裝方式,個人習慣使用 Homebrew,所以就選擇「Homebrew」

安裝 minikube

開啟 Terminal,輸入官網上的 Homebrew 安裝指令

brew install minikube

minikube 常用指令

  • minikube version
    • 用途:查看 minikube 版本
  • minikube status
    • 用途:查看 minikube 狀態
  • minikube start
    • 用途:啟動 minikube
  • minikube stop
    • 用途:停止 minikube

安裝好之後,就可以來啟動 minikube 啦

minikube start

https://ithelp.ithome.com.tw/upload/images/20230917/201403630XJEmOnsuz.png

安裝完 Kubernetes 叢集環境後,就要來撰寫各個 Kubernetes 元件了 (Ex:Pod、Deployment、Service 等)

撰寫 Kubernetes 元件

Deployment (deployment.yaml)

# Kubernetes 中 Deployment 元件的版本
apiVersion: apps/v1

# 該元件的類型
kind: Deployment

# 該元件的元資料
metadata:
  # 這個 Deployment 的名稱
  name: it15th-deployment

# 這個 Deployment 的 DeploymentSpec
spec:
  # 要建立的 Pod 數量
  # 當現有 Pod 數量小於這邊 replica 設定的數值時,就會自動產生對應數量的 Pod 來補齊
  replicas: 2

  # 將更新 Pod 取代舊有 Pod 的政策/策略
  strategy:
    # 這邊的 type 可以設定為 RollingUpdate 或 Recreate
    # RollingUpdate 會逐一更新 Pod,不會將所有 Pod 都停止
    # Recreate 會將所有 Pod 都停止,再重新建立新的 Pod
    type: RollingUpdate

    # 這邊的 maxSurge 設定為 1,表示在更新 Pod 時,最多可以多出 1 個 Pod
    # 這邊的 maxUnavailable 設定為 0,表示在更新 Pod 時,最多可以少 0 個 Pod
    rollingUpdate:
      # 在 RollingUpdate 過程中,要多比 `replica` 設定的數量生幾個 Pod 出來
      # 好處是,可以降低在 RollingUpdate 過程中,舊 Pod 內容出現的機率
      maxSurge: 2

      # 在 RollingUpdate 過程中,可以允許多少數量的 Pod 無法使用
      # 若 maxSurge 不為 0,maxUnavailable 也不得為 0
      maxUnavailable: 2

  # 新建立出來的 Pod 如果沒有任何 Container Crash 的情形發生,
  # 應準備就緒的最小秒數,預設為 0 (即 Pod 準備就緒後就可視為可用)
  minReadySeconds: 60

  # 要保留多少數量可以 RollBack 的舊有 ReplicaSet,預設為 10
  revisionHistoryLimit: 10

  # 要選取的 Pod
  selector:
    matchLabels:
      app: it15th-pod

  # 選到的 Pod 的 PodTemplateSpec
  template:
    # Pod 的元資料
    metadata:
      # Pod 的標籤
      labels:
        app: it15th-pod

    # 選取到的 Pod 的 PodSpec,用來定義 Pod 中的 Containers
    spec:
      # Pod 要執行的 Container
      containers:
        # 選取到的 Pod 內的 Container 名稱
        - name: it15th-container

          # 這個 Container 要用的 Image,預設從 DockerHub 取得
          image: leoho0722/it15th:k8s

          # 宣告這個 Container 要對外開放的 port 類型
          ports:
            # 宣告這個 Container 要對外開放的 port 號
            - containerPort: 8080

          # 宣告這個 Container 要執行的指令
          args: ["./it15th"]

          # 宣告這個 Container 要用的資源
          resources:
            # 這個 Container 最多可以用到的資源
            limits:
              cpu: 200m
              memory: 256Mi

            # 這個 Container 最少要用到的資源
            requests:
              cpu: 100m
              memory: 128Mi

          # 宣告這個 Container 要用的 Volume
          volumeMounts:
            - name: it15th-pv
              mountPath: /mnt/data

      volumes:
        - name: it15th-pv
          persistentVolumeClaim:
            claimName: it15th-pvc

Service (service.yaml)

# Kubernetes 中 Service 元件的版本號
apiVersion: v1

# 該元件的種類
kind: Service

# 該元件的元資料
metadata:
  # 這個 Service 的名稱
  name: it15th-service

# 這個 Service 的 ServiceSpec
spec:
  # Service 要以哪種模式運作
  # Kubernetes 提供 ClusterIP、NodePort、ExternalName、LoadBalancer
  # 預設為 ClusterIP
  type: NodePort

  # 要選取的 Pod
  selector:
    app: it15th-pod

  # 設定 Service 要連接的相關 port 號
  ports:
    - name: it15th-container

      # 決定要以哪種網路協議來進行連線,TCP、UDP、SCTP
      # 預設為 TCP
      protocol: TCP

      # Service 要用哪個 port 號來連到 Pod
      # 通常 port 會跟 targetPort 設定為相同的 port 號
      port: 8080

      # Pod 對外開放的 port 號
      # 沒設定 targetPort 的話,Kubernetes 預設會設為與 port 相同的 port 號
      targetPort: 8080

      # 指定外部連進 Service 的 port 號,範圍為 30000~32767
      # 沒設定 nodePort 的話,Kubernetes 會自動指派一個範圍內的 port 號作為 nodePort
      nodePort: 32000

PersistentVolumeClaim (PVC,pvc.yaml)

# Kubernetes 中 PersistentVolumeClaim 元件的版本號
apiVersion: v1

# 該元件的種類
kind: PersistentVolumeClaim

# 該元件的元資料
metadata:
  # 這個 PersistentVolumeClaim 的名稱
  name: it15th-pvc

# 這個 PersistentVolumeClaim 的 PersistentVolumeClaimSpec
spec:
  # 要求的儲存空間大小
  resources:
    requests:
      storage: 256Mi

  # 要求的儲存空間的卷模式
  volumeMode: Filesystem

  # 要求的儲存空間的存取模式
  accessModes:
    - ReadWriteOnce

  # 要求的儲存空間的儲存類型
  storageClassName: it15th-pv

PersistentVolume (PV,pv.yaml)

# Kubernetes 中 PersistentVolume 元件的版本號
apiVersion: v1

# 該元件的種類
kind: PersistentVolume

# 該元件的元資料
metadata:
  # 這個 PersistentVolume 的名稱
  name: it15th-pv

# 這個 PersistentVolume 的 PersistentVolumeSpec
spec:
  # 該 PersistentVolume 的容量大小
  capacity:
    # 該 PersistentVolume 的容量大小單位
    storage: 1Gi

  # 該 PersistentVolume 的卷模式
  volumeMode: Filesystem

  # 該 PersistentVolume 的存取模式
  accessModes:
    - ReadWriteOnce

  # 該 PersistentVolume 的儲存類型
  # 若不指定,則預設為 default 儲存類型
  storageClassName: it15th-pv

  # 該 PersistentVolume 位於主機上的儲存路徑
  # 僅供單節點的 Kubernetes Cluster 使用
  hostPath:
    # 該 PersistentVolume 的儲存路徑
    path: /mnt/data

    # 該 PersistentVolume 的儲存路徑的類型
    type: DirectoryOrCreate

部署到 Kubernetes 中

上面我們寫好了要使用的 Kubernetes 元件的 yaml 檔,接下來就要實際部署到 Kubernetes 中了

透過 kubectl apply 來將各元件的 yaml 描述檔安裝到 Kubernetes 中

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f pv.yaml
kubectl apply -f pvc.yaml

接著,我們就可以透過 kubectl get all 來查看我們剛剛部署的各元件是否正常運作啦

https://ithelp.ithome.com.tw/upload/images/20230917/201403638hbxbX8e25.png

看起來都有正常運作,那麼我們就可以透過 minikube service <service name> 來啟動

https://ithelp.ithome.com.tw/upload/images/20230917/20140363kZISP64fMd.png

實際用 Postman 來試試看,看有沒有通

https://ithelp.ithome.com.tw/upload/images/20230917/20140363CX0pT2SGRv.png
https://ithelp.ithome.com.tw/upload/images/20230917/20140363LF3CorY23n.png

很好,都有正常運作!

總結

今天我們將前面使用 Go 開發的 Web Backend API 透過 Docker 編譯後,變成容器化應用程式,並且部署到 Kubernetes 上

但在部署的過程中,我們需要手動部署多個元件,這部分我們在明天會來透過 Helm 著手改善

那麼我們明天見~


上一篇
【하나, 둘, ready, get set, go】Day 27 - 整合 GitLab CI 來達成自動化編譯多架構 Docker Image
下一篇
【하나, 둘, ready, get set, go】Day 29 - 改用 Helm 來部署到 Kubernetes 上吧
系列文
【하나, 둘, ready, get set, go】30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言